#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <dirent.h>   // 用于目录读取
#include <string.h>   // 用于字符串操作

#define DEST_PORT 12201
#define BUFFER_SIZE 65536
#define UDP_HEADER_LENGTH 8
#define PACKET_INTERVAL_US 5000 // 每包之间的间隔（微秒）

void process_packet(const u_char *packet, struct pcap_pkthdr packet_header) {
  struct ip *ip_header;
  struct udphdr *udp_header;
  const u_char *payload;
  int ip_header_length;
  int payload_length;

  // Find the IP header
  ip_header = (struct ip *)(packet + 14); // 14 bytes Ethernet header
  ip_header_length = ip_header->ip_hl * 4;

  // Find the UDP header
  udp_header = (struct udphdr *)(packet + 14 + ip_header_length);

  // Find the payload
  payload = packet + 14 + ip_header_length + UDP_HEADER_LENGTH;
  payload_length = ntohs(udp_header->uh_ulen) - UDP_HEADER_LENGTH;

  if (payload_length > 0) {
    // Create a UDP socket
    int sockfd;
    struct sockaddr_in dest_addr;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
      perror("socket");
      return;
    }

    // Set destination address
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(DEST_PORT);
    dest_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // 127.0.0.1

    // Send the payload
    if (payload[payload_length - 1] != '}') puts(payload);
    if (sendto(sockfd, payload, payload_length, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) {
      perror("sendto");
    }

    // Close the socket
    close(sockfd);
  }
}

int main(int argc, char *argv[]) {
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_t *handle;

  if (argc != 2) {
    fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
    return 1;
  }

  DIR *dir;
  struct dirent *entry;

  if ((dir = opendir(argv[1])) == NULL) {
    perror("opendir");
    return 1;
  }

  while ((entry = readdir(dir)) != NULL) {
    // 跳过 "." 和 ".."
    if (entry->d_type == DT_REG) {  // 只处理常规文件
      char filepath[1024];
      snprintf(filepath, sizeof(filepath), "%s/%s", argv[1], entry->d_name);
      fprintf(stdout, "open pcap file %s\n", filepath);

      // Open the pcap file
      handle = pcap_open_offline(filepath, errbuf);
      if (handle == NULL) {
        fprintf(stderr, "Couldn't open pcap file %s: %s\n", filepath, errbuf);
        continue; // 继续处理下一个文件
      }

      // Read packets from the pcap file
      struct pcap_pkthdr packet_header;
      const u_char *packet;
      while ((packet = pcap_next(handle, &packet_header)) != NULL) {
        process_packet(packet, packet_header);
        usleep(PACKET_INTERVAL_US); // 控制发送速率
      }

      // Close the pcap file
      pcap_close(handle);
    }
  }

  closedir(dir);

  return 0;
}

